<!DOCTYPE html>
<html lang="zh-cn" >
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta
      name="author"
      content="awesome404"
    />
      
    <title>Vite打包CDN ｜ 鹊木笔记</title>
    
    
    
    <meta name="description" content="安装NPM包 npm i rollup-plugin-external-globals -D npm i rollup-plugin-commonjs -D 配置Vite 安装好上面两个包后, 按照下面格式进行配置CDN build: { rollupOptions: { external: [&amp;#39;vue&amp;#39;, &amp;#39;vue-router&amp;#39;, &amp;#39;element-plus&amp;#39;, &amp;#39;pinia&amp;#39;, &amp;#39;vue-demi&amp;#39;], plugins: [ commonjs(), externalGlobals({ vue: &amp;#39;Vue&amp;#39;, &amp;#39;pinia&amp;#39;: &amp;#34;Pinia&amp;#34;, &amp;#39;vue-demi&amp;#39;: &amp;#39;VueDemi&amp;#39;, &amp;#39;vue-router&amp;#39;: &amp;#39;VueRouter&amp;#39;, &amp;#39;element-plus&amp;#39;: &amp;#39;ElementPlus&amp;#39;, }), ] } } 配置Index.html 将准备好的 cdn 链接引入index.h" />
      
    <meta
      name="keywords"
      content="Blog, 程序员, 前端"
    />
      <link
    rel="shortcut icon" href="https://awesome404.gitee.io/images/favicon.ico" />

    <link
      rel="stylesheet"
      type="text/css"
      media="screen"
      href="https://awesome404.gitee.io/css/normalize.css"
    />
    <link
      rel="stylesheet"
      type="text/css"
      media="screen"
      href="https://cdn.jsdelivr.net/npm/animate.css@4.1.0/animate.min.css"
    />
    <link rel="stylesheet" type="text/css" media="screen" href="https://awesome404.gitee.io/css/zozo.css" />
    <link
      rel="stylesheet"
      type="text/css"
      media="screen"
      href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css"
    />
    <link rel="stylesheet" type="text/css" media="screen" href="https://awesome404.gitee.io/css/highlight.css" />

    
    
  </head>
</html>


<body>
    <div class="main animate__animated animate__fadeInDown">
        
<div class="nav_container animated fadeInDown">
  <div class="site_nav" id="site_nav">
    <ul>
      
      <li>
        <a href="/">首页</a>
      </li>
      
      <li>
        <a href="/posts/">归档</a>
      </li>
      
      <li>
        <a href="/tags/">标签</a>
      </li>
      
      <li>
        <a href="/about/">关于</a>
      </li>
      
    </ul>
  </div>
  <div class="menu_icon">
    <a id="menu_icon">
      <i class="ri-settings-line"></i>
    </a>
  </div>
</div>

        <div class="header animated fadeInDown">
  <div class="site_title_container">
    <div class="site_title">
      <h1>
        <a href="https://awesome404.gitee.io">
          <span>鹊木笔记</span>
        </a>
      </h1>
    </div>
    <div class="description">
      <p class="sub_title">
        前端菜鸡的自我修养
      </p>
      <div class="my_socials">
         
        <a href="https://github.com/404Awesome" title="github" target="_blank"
          ><i class="ri-github-fill"></i
        ></a>
         
        <a
          href="https://awesome404.gitee.io/index.xml"
          type="application/rss+xml"
          title="rss"
          target="_blank"
          ><i class="ri-rss-fill"></i
        ></a>
      </div>
    </div>
  </div>
</div>

        <div class="content">
            <div class="post_page">
                <div class="post animate__animated animate__fadeInDown">
                    <div class="post_title post_detail_title">
                        <h2><a href='/posts/vite%E6%89%93%E5%8C%85cdn/'>Vite打包CDN</a></h2>
                        <span class="date">2022.06.21</span>
                    </div>
                    <div class="post_content markdown"><h2 id="安装npm包">安装NPM包</h2>
<blockquote>
<p>npm i rollup-plugin-external-globals -D</p>
<p>npm i rollup-plugin-commonjs -D</p>
</blockquote>
<h2 id="配置vite">配置Vite</h2>
<p>安装好上面两个包后, 按照下面格式进行配置CDN</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">build</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">rollupOptions</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">external</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;vue&#39;</span><span class="p">,</span> <span class="s1">&#39;vue-router&#39;</span><span class="p">,</span> <span class="s1">&#39;element-plus&#39;</span><span class="p">,</span> <span class="s1">&#39;pinia&#39;</span><span class="p">,</span> <span class="s1">&#39;vue-demi&#39;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nx">plugins</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="nx">commonjs</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">        <span class="nx">externalGlobals</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">          <span class="nx">vue</span><span class="o">:</span> <span class="s1">&#39;Vue&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s1">&#39;pinia&#39;</span><span class="o">:</span> <span class="s2">&#34;Pinia&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s1">&#39;vue-demi&#39;</span><span class="o">:</span> <span class="s1">&#39;VueDemi&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s1">&#39;vue-router&#39;</span><span class="o">:</span> <span class="s1">&#39;VueRouter&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s1">&#39;element-plus&#39;</span><span class="o">:</span> <span class="s1">&#39;ElementPlus&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">}),</span>
</span></span><span class="line"><span class="cl">      <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="配置indexhtml">配置Index.html</h3>
<p>将准备好的 cdn 链接引入index.html页面即可</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">charset</span><span class="o">=</span><span class="s">&#34;UTF-8&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;icon&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;/favicon.ico&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;viewport&#34;</span> <span class="na">content</span><span class="o">=</span><span class="s">&#34;width=device-width, initial-scale=1.0&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;//unpkg.com/element-plus@2.1.11/dist/index.css&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;//cdn.jsdelivr.net/npm/vue@3.2.25/dist/vue.global.prod.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;//cdn.jsdelivr.net/npm/vue-router@4.0.14/dist/vue-router.global.prod.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;//cdn.jsdelivr.net/npm/element-plus@2.1.11/dist/index.full.min.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;//cdn.jsdelivr.net/npm/vue-demi@0.12.5&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;//cdn.jsdelivr.net/npm/pinia@2.0.13&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>CloudMusic<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>配置完成后执行 npm run build 开始打包</p>
<p>打包后可以执行 npm run preview 查看效果</p>
<h2 id="打包遇到的坑">打包遇到的坑</h2>
<blockquote>
<p>Uncaught TypeError: Failed to resolve module specifier &ldquo;vue&rdquo;. Relative references must start with either &ldquo;/&rdquo;, &ldquo;./&rdquo;, or &ldquo;../&rdquo;.</p>
</blockquote>
<p>问题原因发生在 Pinia上, 上方代码原本是没有将 vue-demi 库打包成cdn的, 所以打包完后会出现上方错误, 因为 Pinia 依赖于 vue-demi 库, 而 vue-demi 库又依赖于 vue, 但是 vue 库成为了 cdn 链接的形式，暴露的是 Vue 这个变量, 导致 vue-demi 库找不到 vue 而报错, 所以将 vue-demi 库也打包成 cdn, 就可以解决这个问题。</p>
<p>需要注意在 index.html 里引入的顺序很重要 vue-demi 库不能在 pinia 库的上面, 会报错。</p>
<p>这里用 Pinia 举例, 如过发生相似问题, 可以从库依赖下手。</p>
</div>
                    <div class="post_footer">
                        
                        
                        <div id="link">
                            <p>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0协议 。转载请注明出处！</p>
                            <p><span id="link_href"></span><i class="ri-file-copy-2-line link_btn"></i></p>
                        </div>
                        
                        <div class="meta">
                            <div class="info">
                                <span class="field tags">
                                    <i class="ri-price-tag-2-line"></i>
                                    
                                    <a href="https://awesome404.gitee.io/tags/vite/">Vite</a>
                                    
                                    <a href="https://awesome404.gitee.io/tags/cdn/">CDN</a>
                                    
                                </span>
                            </div>
                        </div>
                        
                    </div>
                </div>
                
                
            </div>
        </div>
    </div>
    <a id="back_to_top" href="#" class="back_to_top"><i class="ri-arrow-up-s-line"></i></a>
    
<style>
  #hitokoto {
    overflow: hidden;
    margin: 0 auto;
    width: 80%;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 16px;
    color: #424242;
  }

  .footer {
    padding: 30px 0px;
  }
</style>

<footer class="footer">
  <p id="hitokoto">:D 获取中...</p>
</footer>

<script>
  fetch("https://v1.hitokoto.cn")
    .then((response) => response.json())
    .then((data) => {
      const hitokoto = document.getElementById("hitokoto");
      hitokoto.href = "https://hitokoto.cn/?uuid=" + data.uuid;
      hitokoto.innerText = data.hitokoto;
    })
    .catch((err) => err);
</script>

    <script src="https://awesome404.gitee.io/js/jquery-3.5.1.min.js"></script>
<link href="https://awesome404.gitee.io/css/fancybox.min.css" rel="stylesheet">
<script src="https://awesome404.gitee.io/js/fancybox.min.js"></script>
<script src="https://awesome404.gitee.io/js/zozo.js"></script>




</body>


<script>
    (function (){
        
        function handleIcon (remove, target){
            this.classList.remove(remove);
            this.classList.add(target);
        }

        let hrefEl = document.getElementById("link_href");
        let copyBtn = document.getElementsByClassName("link_btn")[0];
        if (hrefEl){
            hrefEl.innerText = `文章链接: ${location.href}`;
            
            copyBtn.onclick = (event) => {
                
                navigator.clipboard.writeText(`文章转载自: ${location.href}`)
                
                handleIcon.call(event.target, "ri-file-copy-2-line", "ri-check-line");
                let timer = setTimeout(() => {
                    handleIcon.call(event.target, "ri-check-line", "ri-file-copy-2-line");
                    clearTimeout(timer)
                }, 1000)
            }
        }
    })();
</script>
</html>